#pragma once
#include <vector>
#include "GOD.h"
#include "Object.h"

class Action
{
public:
	std::vector<Condition> pre;
	std::vector<Condition> post;
	//std::vector<Condition> executionPre; // precondition required only for execution, not for planning.  If this fails, 

	float animationTime; // in the future, this will be a handle to the scripted animation to play that achieves the post conditions of the action.
	char * name;
	SGKAgent * m_pOwner;

	bool satisfies(Condition * inQuestion);
	virtual char * GetName() = 0;
	virtual bool satisfied() = 0;
	virtual void activate() = 0;
	virtual ~Action(){};
};


// And now, ladies and gentlemen: we will derive actions from action.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////																										
// bool satisfied: hard-coded boolean expression determining if the action is DO-able.(checks pre-conditions)//
// bool satisfies: checks if action satisfies a specific condition																										 //
// The code inside of the activate() function sets the A.I. into some state, and sets						 //
//		some parameters.  For example, the Flee action sets the A.I. into the Goto state, and sets			 //
//		some specific destination to run to.  Our C++ class for an action looks something like this:		 //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
class ActionFireWeapon : public Action
{
public:
	ActionFireWeapon(SGKAgent * owner = NULL)
	{
		m_pOwner = owner;
		animationTime = 1.0f;
		post.push_back(Condition(PLAYERHURT, value(true)));
		post.push_back(Condition(GUNAIMED, value(false)));
		pre.push_back(Condition(GUNAIMED, value(true)));
	}
	void activate();
	bool satisfied();
	char * GetName(){return "FireWeapon";}
};

class ActionMountTurret : public Action
{
public:
	ActionMountTurret(SGKAgent * owner = NULL)
	{
		m_pOwner = owner;
		animationTime = 1.0f;
		//pre.push_back(Condition(CANGETOBJ, value(GUN)));
		pre.push_back(Condition(ATOBJ, value(GUN)));
		post.push_back(Condition(HASOBJ, value(GUN)));
	}
	void activate();
	bool satisfied();
	char * GetName(){return "MountTurret";}
};

class ActionAimGun : public Action
{
public:
	ActionAimGun(SGKAgent * owner = NULL)
	{
		m_pOwner = owner;
		animationTime = 1.0f;
		pre.push_back(Condition(HASOBJ, value(GUN)));
		post.push_back(Condition(GUNAIMED, value(true)));
	}
	void activate();
	bool satisfied();
	char * GetName(){return "AimGun";}
};

class ActionMelee : public Action
{
public:
	ActionMelee(SGKAgent * owner = NULL)
	{
		m_pOwner = owner;
		animationTime = 1.0f;
		pre.push_back(Condition(CANTGETOBJ, value(GUN)));
		pre.push_back(Condition(ATOBJ, value(PLAYER)));
		post.push_back(Condition(PLAYERHURT, value(true)));
	}
	void activate();
	bool satisfied();
	char * GetName(){return "Melee";}
};

class ActionGOTO : public Action
{
public:
	ActionGOTO(SGKAgent * owner = NULL)
	{
		m_pOwner = owner;
		animationTime = 1.0f;
		pre.push_back(Condition(WANTSOBJ, value(GUN)));
		post.push_back(Condition(ATOBJ, value(GUN)));
	}
	void activate();
	bool satisfied();
	char * GetName(){return "Goto";}
};

class ActionJustChillin : public Action
{
public:
	ActionJustChillin(SGKAgent * owner = NULL)
	{
		m_pOwner = owner;
		animationTime = 1.0f;
		post.push_back(Condition(WANTSOBJ, value(GUN)));
		post.push_back(Condition(WANTSOBJ, value(PLAYER)));
	}
	void activate();
	bool satisfied();
	char * GetName(){return "JustChilling";}
};

class ActionGotoPlayer : public Action
{
public:
	ActionGotoPlayer(SGKAgent * owner = NULL)
	{
		m_pOwner = owner;
		animationTime = 1.0f;
		pre.push_back(Condition(WANTSOBJ, value(PLAYER)));
		post.push_back(Condition(ATOBJ, value(PLAYER)));
	}
	void activate();
	bool satisfied();
	char * GetName(){return "SeekPlayer";}
};

